package com.android.example.app3;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.media.Image;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.provider.Settings;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.renderscript.Type;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.SpannedString;
import android.text.style.AbsoluteSizeSpan;
import android.util.Log;
import android.util.Size;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.exifinterface.media.ExifInterface;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.mlkit.vision.barcode.Barcode;
import com.google.mlkit.vision.barcode.BarcodeScanner;
import com.google.mlkit.vision.barcode.BarcodeScanning;
import com.google.mlkit.vision.common.InputImage;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MainActivity extends AppCompatActivity implements ItemRemovedListener {

    private static final String TAG = "MainActivity";
    private ErrorLogger errorLogger;
    private UpdateManager updateManager;


    private static final int MY_PERMISSIONS_REQUEST_CAMERA = 100;
    private static final LinkedList<String> photoList = new LinkedList<>();
    private static final LinkedList<String> danhaoList = new LinkedList<>();
    private SharedViewModel viewModel;
    private ExecutorService executor;// 确保异步处理图像分析
    private PreviewView previewView;
    private TextView scanresult;

    private static final int PERMISSIONS_REQUEST_CODE = 1001;

    private static final int PICK_FILE_REQUEST = 1;
    private int photoList_count = 0;
    private int danhaoList_count = 0;

    private TextView clearButton;

    private ImageCapture imageCapture;
    // 条形码扫描器
    private BarcodeScanner barcodeScanner;
    private TextView textViewToCopy;
    private TextView textView4;
    private TextView textView2;
    private TextView textView;
    private TextView viewlist;
    private TextView textView5;
    private TextView textView6;
    private EditText editText;
    private Camera camera;
    private boolean saveTorchState;
    private boolean repeat;
    private ImageView torchToggle;
    private ImageView imageView;
    private ImageView imageView1;
    private ImageView scanButton;
    private ImageView scanButton1;
    private List<ImageItem> imageItems;
    private ImageAdapter_list mAdapter;

    private RecyclerView mRecyclerView;
    private RecyclerView mRecyclerView1;
    private String Name;
    private String ScanResult;
    private String danhaoyicunzai = "null";
    private String lastScanResult = null; // 用于存储上一次扫描的结果
    private long lastScanTime = 0;        // 用于记录上一次扫描的时间
    private String Name1;
    private boolean time = true;
    private ImageItem item;

    private BeepHelper beepHelper;

    private static Bitmap imageToBitmap(Context context, Image image) {
        if (image == null) return null;

        try {
            // 获取图像参数
            int width = image.getWidth();
            int height = image.getHeight();
            Image.Plane[] planes = image.getPlanes();

            // 获取YUV平面数据
            ByteBuffer yBuffer = planes[0].getBuffer();
            ByteBuffer uBuffer = planes[1].getBuffer();
            ByteBuffer vBuffer = planes[2].getBuffer();

            // 获取平面参数（注意跨距处理）
            int yRowStride = planes[0].getRowStride();
            int uvRowStride = planes[1].getRowStride();
            int uvPixelStride = planes[1].getPixelStride();

            // 创建正确格式的NV21数据
            byte[] nv21 = new byte[width * height * 3 / 2];

            // 拷贝Y分量（处理行跨距）
            copyPlane(yBuffer, nv21, 0, width, height, yRowStride, 1);

            // 合并UV分量（处理跨距和交错）
            int uvWidth = width / 2;
            int uvHeight = height / 2;
            copyUVInterleaved(uBuffer, vBuffer, nv21, width * height,
                    uvWidth, uvHeight, uvRowStride, uvPixelStride);

            // 使用RenderScript高效转换（API 17+）
            Bitmap bitmap = createBitmapViaRenderScript(context, nv21, width, height);

            // 备用方案：使用YuvImage（当RenderScript不可用时）
            // Bitmap bitmap = createBitmapViaYuvImage(nv21, width, height);

            return bitmap;
        } finally {
            // 确保资源释放

        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        // 检查并请求必要的权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // Android 13 及以上版本的权限申请
            checkAndRequestPermissionsForAndroid13AndAbove();
        } else {
            // Android 12 及以下版本的权限申请
            checkAndRequestPermissionsForAndroid12AndBelow();
        }

    }

    @Override
    protected void onStop() {
        super.onStop();
        // 设置焦点false
        editText.setFocusableInTouchMode(false);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 清理其他可能的资源，比如线程池等

    }


    /**
     * 以下为实现对象类
     */

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == MY_PERMISSIONS_REQUEST_CAMERA) {// 如果请求被用户授予
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 相机权限被授予，可以安全地访问相机
                startCamera();
            } else {
                //相机权限未授予
                Toast.makeText(this, "为了能让您使用拍照功能，我们需要您授予相机权限", Toast.LENGTH_SHORT).show();
            }
        }
    }


    private void showPermissionDeniedDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);

        builder.setTitle("相机权限未被授予");
        builder.setMessage("为了正常使用应用功能，请允许“相机权限”。");
        builder.setPositiveButton("去设置", (dialog, which) -> {
            // 尝试引导用户去设置页面手动授予权限
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                    Uri.fromParts("package", getPackageName(), null));
            startActivity(intent);
        });
        builder.setNegativeButton("取消", (dialog, which) -> Toast.makeText(this, "为了能让您使用拍照功能,需要您授予“相机权限”", Toast.LENGTH_SHORT).show());
        builder.show();
    }


    private void openFilePicker() {
        // 启动文件选择器
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("*/*"); // 允许选择所有类型的文件
        startActivityForResult(intent, PICK_FILE_REQUEST);
    }

    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // 检查Intent是否是ACTION_VIEW并且数据类型是图片文件
        if (requestCode == PICK_FILE_REQUEST && resultCode == RESULT_OK && data != null) {
            Uri uri = data.getData();
            if (uri != null) {
                String type = getContentResolver().getType(uri);
                if (type != null && type.startsWith("image/")) {
                    // 这里可以添加逻辑来处理图片文件，例如显示图片
                    Intent intent = new Intent(this, MainActivity2.class);
                    intent.putExtra("image_uri", uri);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
//                    handleImage(uri);
                } else {
                    // 处理非图片文件的情况
                    Toast.makeText(this, "选择的文件不是图片", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

    private void handleImage(Uri uri) {
        // 在这里实现处理图片的逻辑，例如显示图片
        // 示例：使用ImageView显示图片
        Toast.makeText(this, "打开图片文件：" + uri, Toast.LENGTH_SHORT).show();
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(uri, "image/*");
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivity(intent);
    }

    // 辅助函数，用于清理并格式化文件名，确保安全合法
    private String sanitizeFileName(String name) {
        return name.replaceAll("[^a-zA-Z0-9._-]", "");
    }


    private void checkAndRequestPermissionsForAndroid13AndAbove() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (hasCameraPermission() || !hasReadMediaImagesPermission()) {
                // 请求权限
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES},
                        PERMISSIONS_REQUEST_CODE);
            } else {
                // 权限已经被授予，可以继续使用相机
                startCamera();
            }
        }

    }
    private void checkAndRequestPermissionsForAndroid12AndBelow() {
        if (hasCameraPermission() || !hasReadExternalStoragePermission()) {
            // 请求权限
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE},
                    PERMISSIONS_REQUEST_CODE);
        } else {
            // 权限已经被授予，可以继续使用相机
            startCamera();
        }
    }

    private boolean hasCameraPermission() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED;
    }

    @RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
    private boolean hasReadMediaImagesPermission() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED;
    }

    private boolean hasReadExternalStoragePermission() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
    }

    private void navigateToActivity() {
        Intent intent = new Intent(this, MainActivity4.class);
        startActivity(intent);
    }

    private void copyToClipboard(String text) {
        if (text == null || text.isEmpty()) {
            // 显示提示信息或执行其他操作
            Toast.makeText(this, "扫描结果文本为空或为null", Toast.LENGTH_SHORT).show();
            return;
        }

        ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clip = ClipData.newPlainText("text", text);
        clipboardManager.setPrimaryClip(clip);
        Toast.makeText(this, "文本已复制到剪贴板", Toast.LENGTH_SHORT).show();
    }

    private void toggleTorch() {
        saveTorchState = !saveTorchState;
        if (saveTorchState) {
            // 打开手电筒
            if (camera != null) {
                camera.getCameraControl().enableTorch(true);
                saveTorchState = true;
            }
            torchToggle.setImageResource(R.drawable.ml_flashlight_on);
        } else {
            // 关闭手电筒
            if (camera != null) {
                camera.getCameraControl().enableTorch(false);
                saveTorchState = false;
            }
            torchToggle.setImageResource(R.drawable.ml_flashlight_off);
        }
    }


    // 隐藏软键盘的方法
    // 输入框失去焦点时收起软键盘
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        View view = getCurrentFocus();
        if ((view instanceof EditText)) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 清理其他可能的资源，比如线程池等
        if (executor != null && !executor.isShutdown()) {
            // 当不再提交任何任务时，关闭线程池
            executor.shutdown();
        }
        beepHelper.release();

    }
    // 正则表达式匹配手机号码
    private boolean isPhoneNumber(String text) {
        Pattern pattern = Pattern.compile("^(\\+86|86|\\+86-|86-)?1[3-9]\\d{9}$");
        Matcher matcher = pattern.matcher(text);
        return matcher.matches();
    }

    // 处理识别到的手机号码
    private void handlePhoneNumber(String phoneNumber) {
        // 在这里实现手机号码的处理逻辑，例如显示在界面上或者进行其他操作
        System.out.println("识别到的手机号码: " + phoneNumber);
    }

    @Override
    protected void onStart() {
        super.onStart();
        // 调用 updateRulesFile 方法来更新规则文件
        ExpressNumberValidator.updateRulesFile(this);
        updateRulesFile("photoList.txt");
        // 计算列表中的元素数量
        photoList_count = photoList.size();
        danhaoList_count = danhaoList.size();
        // 显示扫描结果视图
        textView2.setText(String.valueOf(photoList_count));
        textView.setText(String.valueOf(danhaoList_count));
        // 隐藏软键盘的方法
        editText.setFocusable(false);
        // 切换到关闭图标
        torchToggle.setImageResource(R.drawable.ml_flashlight_off);
        // 在扫描界面创建时提前初始化
        beepHelper = new BeepHelper();
        beepHelper.init(this, R.raw.smdi);

    }


    private void sonfirmDeniedDialog(String Name) {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setTitle("请注意!")
                .setMessage(Name + "\n照片已存在，是否查看历史记录照片？")
                .setPositiveButton("查看", (dialog, id) -> {
                    // 用户点击“确定”按钮后执行的代码
                    Intent intent = new Intent(this, ImageGalleryActivity.class);
                    intent.putExtra("key_string", Name);
                    startActivity(intent);
                })
                .setNegativeButton("取消", (dialog, id) -> {
                    // 用户点击“取消”按钮后执行的代码
                });
        AlertDialog dialog = builder.create();
        dialog.show();
    }

    /**
     * 更新UI显示扫描结果
     *
     * @param result 扫描结果字符串
     */
    private void updateUIWithScanResult(String result) {
        runOnUiThread(() -> {
            scanresult.setText(result); // 设置扫描结果显示文本
            scanresult.setVisibility(View.VISIBLE);
            scanButton.setVisibility(View.VISIBLE);
        }); // 显示扫描结果视图
    }

    // 通用的播放声音方法，用于资源管理和释放
    private void playSound(int soundResId) {
        runOnUiThread(() -> {
            MediaPlayer mediaPlayer = MediaPlayer.create(this, soundResId);
            mediaPlayer.setOnCompletionListener(MediaPlayer::release); // 播放完成后释放资源
            mediaPlayer.start();// 开始播放
        });
    }

    // 高效拷贝平面数据（跳过行填充）
    private static void copyPlane(ByteBuffer src, byte[] dst, int offset,
                                  int width, int height, int rowStride, int pixelStride) {
        for (int row = 0; row < height; row++) {
            src.position(row * rowStride);
            int dstPos = offset + row * width;
            for (int col = 0; col < width; col++) {
                dst[dstPos++] = src.get();
                src.position(src.position() + pixelStride - 1);
            }
        }
    }

    // 将ImageProxy转换为Bitmap
    private Bitmap imageProxyToBitmap(ImageProxy image) {
        ImageProxy.PlaneProxy[] planes = image.getPlanes();
        ByteBuffer buffer = planes[0].getBuffer();
        buffer.rewind();
        byte[] bytes = new byte[buffer.capacity()];
        buffer.get(bytes);
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    //拍照方法
    public void takePicture(String Name) {

        // 拍照并保存图片
        File photoFile = new File(getExternalFilesDir(null), "image.png");
        ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(photoFile).build();
        imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(this),
                new ImageCapture.OnImageSavedCallback() {
                    @Override
                    public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
                        playSound(R.raw.paizhaochenggong);//播放拍照成功声音
                        Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
                        Bitmap rotatedBitmap = rotateBitmapAccordingToExif(photoFile, bitmap);
                        //保存图片
                        saveCapturedImageToPtFolder(Name, rotatedBitmap);
                    }

                    @Override
                    public void onError(@NonNull ImageCaptureException error) {
                        String errorMsg = "照片保存失败: " + error.getMessage();
                        Toast.makeText(MainActivity.this, Name + "照片保存失败.", Toast.LENGTH_SHORT).show();
                        Log.e("app3", errorMsg, error);
                    }
                });
    }


    // 交错UV分量（处理跨距）
    private static void copyUVInterleaved(ByteBuffer uSrc, ByteBuffer vSrc, byte[] dst, int offset,
                                          int uvWidth, int uvHeight, int uvRowStride, int uvPixelStride) {
        // 创建只读视图防止修改原始buffer状态
        ByteBuffer uView = uSrc.asReadOnlyBuffer();
        ByteBuffer vView = vSrc.asReadOnlyBuffer();

        for (int row = 0; row < uvHeight; row++) {
            // 计算行起始位置（不超过缓冲区限制）
            int uRowPos = Math.min(row * uvRowStride, uView.limit() - 1);
            int vRowPos = Math.min(row * uvRowStride, vView.limit() - 1);

            uView.position(uRowPos);
            vView.position(vRowPos);

            int dstPos = offset + row * uvWidth * 2;
            int colsRemaining = uvWidth;

            while (colsRemaining-- > 0) {
                // 检查缓冲区剩余空间
                if (uView.remaining() < uvPixelStride ||
                        vView.remaining() < uvPixelStride) break;

                // 直接读取不修改position
                dst[dstPos++] = vView.get(vView.position()); // V分量
                dst[dstPos++] = uView.get(uView.position()); // U分量

                // 安全移动指针
                uView.position(uView.position() + uvPixelStride);
                vView.position(vView.position() + uvPixelStride);
            }
        }
    }

    // 使用RenderScript高效转换（API 17+）
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    private static Bitmap createBitmapViaRenderScript(Context context, byte[] nv21, int width, int height) {
        RenderScript rs = RenderScript.create(context);
        ScriptIntrinsicYuvToRGB yuvToRgb = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));

        Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs))
                .setX(nv21.length);
        Allocation input = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
        input.copyFrom(nv21);

        Type.Builder rgbType = new Type.Builder(rs, Element.RGBA_8888(rs))
                .setX(width)
                .setY(height);
        Allocation output = Allocation.createTyped(rs, rgbType.create(), Allocation.USAGE_SCRIPT);

        yuvToRgb.setInput(input);
        yuvToRgb.forEach(output);

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        output.copyTo(bitmap);

        rs.destroy(); // 释放RenderScript资源
        return bitmap;
    }

    // 备用方案：YuvImage转换（兼容旧API）
    private static Bitmap createBitmapViaYuvImage(byte[] nv21, int width, int height) {
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            YuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
            yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, out);
            byte[] jpegData = out.toByteArray();
            return BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length);
        } catch (IOException e) {
            return null;
        }
    }

    /**
     * 初始化Camera
     */



    private void startCamera() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            // 请求CAMERA权限
            // 请求CAMERA权限
            showPermissionDeniedDialog();
        }

        // 将Camera的生命周期和Activity绑定在一起（设定生命周期所有者），这样就不用手动控制相机的启动和关闭。
        ListenableFuture<ProcessCameraProvider> processCameraProviderListenableFuture;
        processCameraProviderListenableFuture = ProcessCameraProvider.getInstance(this);
        processCameraProviderListenableFuture.addListener(() -> {
            try {
                /* 配置预览 */
                previewView.setScaleType(PreviewView.ScaleType.FIT_CENTER);
                Preview preview = new Preview.Builder().build();
                preview.setSurfaceProvider(previewView.getSurfaceProvider());
                /*
                实例化（可以设置许多属性)
                 设置预览帧分析
                */

                // 初始化执行器
                barcodeScanner = BarcodeScanning.getClient();
                ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
                        .setTargetResolution(new Size(720, 1280))
                        .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
                        .build();
                imageAnalysis.setAnalyzer(executor, this::scanBarcode);


                // 配置ImageCapture实例，设置自定义图片尺寸
                imageCapture = new ImageCapture.Builder()
                        .setTargetResolution(new Size(720, 1280))
                        .setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY) // 优先保证质量
                        .build();

                //绑定到生命周期
                ProcessCameraProvider processCameraProvider = processCameraProviderListenableFuture.get();
                processCameraProvider.unbindAll();
                camera = processCameraProvider.bindToLifecycle(MainActivity.this, CameraSelector.DEFAULT_BACK_CAMERA, preview, imageCapture, imageAnalysis);
            } catch (ExecutionException | InterruptedException e) {
                Log.e(TAG, "startCamera: ", e);
            }
        }, ContextCompat.getMainExecutor(this));
    }

    // 捕获图片
    public void captureImage(String Name) {
        //播放提示
        beepHelper.playBeep();
        imageCapture.takePicture(
                ContextCompat.getMainExecutor(this),
                new ImageCapture.OnImageCapturedCallback() {
                    @Override
                    public void onCaptureSuccess(@NonNull ImageProxy image) {
                        // 将ImageProxy转换为Bitmap
                        Bitmap capturedBitmap = imageProxyToBitmap(image);
                        //保存图片
                        saveCapturedImageToPtFolder(Name, capturedBitmap);
                        image.close();
                    }

                    @Override
                    public void onError(@NonNull ImageCaptureException exception) {
                        // 捕获失败
                        Toast.makeText(MainActivity.this, "捕获图片失败: " + exception.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                }
        );
    }

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 初始化错误日志记录器
        ErrorLogger.getInstance(this).initialize();
        EdgeToEdge.enable(this);

        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.previewView), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
        //初始化控件
        scanButton = findViewById(R.id.scanButton);//按钮拍摄图片
        scanButton1 = findViewById(R.id.scanButton1);//按钮拍摄图片
        ImageView button3 = findViewById(R.id.button3);//规则
        viewlist = findViewById(R.id.viewlist);//查看扫描记录
        imageView = findViewById(R.id.imageView);//搜索记录
        imageView1 = findViewById(R.id.imageView1);//显示图片
        editText = findViewById(R.id.editText);// 手动输入框
        scanresult = findViewById(R.id.scanresultTextView);//扫描内容显示
        previewView = findViewById(R.id.previewView);//相机预览
        torchToggle = findViewById(R.id.torchToggle);//闪光灯
        textView = findViewById(R.id.textView);//daohaoList数量
        clearButton = findViewById(R.id.textView1);//搜索记录
        textView2 = findViewById(R.id.textView2);// photoList数量
        textView4 = findViewById(R.id.textView4);//显示扫描记录
        textView5 = findViewById(R.id.textView5);//复制扫描记录
        textView6 = findViewById(R.id.textView6);//清空扫描记录
        mRecyclerView = findViewById(R.id.recycler_view);
        Name = null;
        saveTorchState = false;
        repeat = true;
        // 锁定竖屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        SpannableString ss = new SpannableString("可选择输入日期或单号进行搜索或拍照");//定义hint的值
        AbsoluteSizeSpan ass = new AbsoluteSizeSpan(12, true);//设置字体大小 true表示单位是sp
        ss.setSpan(ass, 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        editText.setHint(new SpannedString(ss));
        //当软键盘弹出时，Activity的窗口会调整大小，但内容布局会向上滚动，以避免被键盘覆盖。
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED);


        // 例如，在按钮点击事件或应用启动时调用检查更新
//        new UpdateChecker(this).checkForUpdates();

        // 添加默认规则
        new ExpressNumberValidator();// 调用构造函数以添加默认规则
        updateRulesFile("danhaoList.txt");//更新照片名称文件
        // 设置监听器
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new ImageAdapter_list(new ArrayList<>());
        mAdapter.setItemRemovedListener(this);
        mRecyclerView.setAdapter(mAdapter);
        executor = Executors.newSingleThreadExecutor();

        viewModel = new ViewModelProvider(this).get(SharedViewModel.class);
        viewModel.setItemList(danhaoList);
        // 观察列表数据变化
        viewModel.getItemList().observe(this, items -> {

        });

        updateManager = new UpdateManager(this);
        updateManager.setListener(new UpdateManager.UpdateListener() {
            @Override
            public void onUpdateAvailable(String versionName, String downloadUrl) {
                // 显示更新提示对话框
                showUpdateDialog(versionName, downloadUrl);
            }

            @Override
            public void onUpdateFailed(String errorMsg) {
                Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onDownloadProgress(int progress) {
                // 更新下载进度条
            }

            @Override
            public void onInstallReady(File apkFile) {
                // 下载完成，准备安装
                updateManager.installApk(apkFile);
            }
        });

        /*  //以下为点击事件*/

        scanresult.setOnClickListener(v -> copyToClipboard(scanresult.getText().toString()));
        textView.setOnClickListener(v -> {
            openFileWithApp("danhaoList.txt");
//            Intent intent = new Intent(this, ScanRecordActivity.class);
//            intent.putExtra("key_string", "danhaoList");
//            startActivity(intent);
        });
        textView2.setOnClickListener(v -> {
            openFileWithApp("photoList.txt");
        });

        imageView1.setOnClickListener(v -> {
            Intent intent = new Intent(this, ImageGalleryActivity.class);
            intent.putExtra("key_string", Name);
            startActivity(intent);
        });
        textView5.setOnClickListener(v -> {
            // 将 LinkedList 转换为字符串（每行一个元素）
            StringBuilder sb = new StringBuilder();
            for (String photo : danhaoList) {
                sb.append(photo).append("\n"); // 用换行符分隔每个元素
            }
            String clipboardContent = sb.toString().trim(); // 移除末尾多余的换行符
            // 将字符串复制到剪贴板
            copyToClipboard(clipboardContent);
        });
        textView6.setOnClickListener(v -> {
            mRecyclerView.setVisibility(View.INVISIBLE);
            // 检查列表是否为空
            if (!danhaoList.isEmpty()) {
                // 清空列表
                danhaoList.clear();
                textView.setText("0");
                ClearFileExample.clearFile(this, "danhaoList.txt");
                if (mAdapter != null) {
                    List<ImageItem> imageItems = mAdapter.getImageItems(); // 假设你的 Adapter 有一个 getImageItems() 方法
                    if (imageItems != null) {
                        imageItems.clear(); // 清空数据集
                        mAdapter.notifyDataSetChanged(); // 通知数据变化
                    }
                }

            }
            DeleteFileExample.deleteFile(this, "danhaoList.txt");
        });
        // 手电筒开关
        torchToggle.setOnClickListener(v -> toggleTorch());
        // 点击规则
        button3.setOnClickListener(v -> navigateToActivity());
//        // 清空EditText的文字
//        clearButton.setOnClickListener(v -> {editText.setText(""); scanresult.setText(null);});
        // 复制textViewToCopy的内容到剪贴板
//        textViewToCopy.setOnClickListener(v -> {
//            // 计算列表中的元素数量
//            int photoList_count = photoList.size();  // 正确用法
//
//        });
        //  editText请求焦点
        editText.setOnClickListener(v -> {
            // 请求焦点
            editText.setFocusableInTouchMode(true);
            editText.requestFocus();
            // 显示软键盘
            InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
        });

        // 搜索EditText的文字
        clearButton.setOnClickListener(v -> {
            // 应用需获得了分区存储权限
            String Name1 = sanitizeFileName(editText.getText().toString());
            Intent intent = new Intent(this, ImageGalleryActivity.class);
            intent.putExtra("key_string", Name1);
            startActivity(intent);
        });
        //打开文件
        imageView.setOnClickListener(v -> {
            // 应用需获得了分区存储权限
            openFilePicker();
        });

        //点击拍照按钮操作
        scanButton1.setOnClickListener(v -> {
            // 更新上一次扫描时间
            lastScanTime = System.currentTimeMillis();
            repeat = true;
            Name1 = sanitizeFileName(editText.getText().toString());
            if (Name1.isEmpty()) {
                Name1 = new SimpleDateFormat("yyyyMMdd", Locale.getDefault()).format(new Date());
            }
            Name = Name1;
            int i = 1;
            while (photoList.contains(Name)) {
                Name = Name1 + "_" + i;
                i++;
            }
//            takePicture(Name);
            captureImage(Name);
            updateUIWithScanResult(Name);
        });
        //点击拍照按钮操作
        scanButton.setOnClickListener(v -> {
            // 更新上一次扫描时间
            lastScanTime = System.currentTimeMillis();
            repeat = true;
            Name1 = sanitizeFileName(scanresult.getText().toString());
            if (Name1.isEmpty()) {
                Name1 = new SimpleDateFormat("yyyyMMdd", Locale.getDefault()).format(new Date());
            }
            Name = Name1;
            int i = 1;
            while (photoList.contains(Name)) {
                Name = Name1 + "_" + i;
                i++;
            }
//            takePicture(Name);
            captureImage(Name);
            updateUIWithScanResult(Name);
        });
    }

    private void showUpdateDialog(String version, String downloadUrl) {
        new AlertDialog.Builder(this)
                .setTitle("发现新版本")
                .setMessage("最新版本: " + version)
                .setPositiveButton("立即更新", (dialog, which) -> {
                    updateManager.downloadApk(downloadUrl);
                })
                .setNegativeButton("稍后提醒", null)
                .show();
    }

    // 在按钮点击等位置调用检查更新
    public void checkUpdate(View view) {
        updateManager.checkForUpdate();
    }

    public ErrorLogger getErrorLogger() {
        return errorLogger;
    }
    /**
     * 该方法 scanBarcode 是用于扫描条形码的功能实现，
     * 它接收来自相机流的 ImageProxy 对象并进行处理以检测条形码
     */
    @SuppressLint("SetTextI18n")
    private void scanBarcode(ImageProxy imageProxy) {
        executor.submit(() -> {
            @SuppressLint("UnsafeOptInUsageError") Image mediaImage = imageProxy.getImage();
            long currentTime = System.currentTimeMillis();//设置时间戳
            if (mediaImage != null) {
                InputImage inputImage = InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
                barcodeScanner.process(inputImage)
                        .addOnSuccessListener(barcodes -> {
                            if (!barcodes.isEmpty()) { // 判断是否至少有一个条形码
                                for (Barcode barcode : barcodes) {
                                    runOnUiThread(() -> {
                                        ScanResult = barcode.getRawValue();
                                        if (ScanResult != null) {
                                            Name = ScanResult.replaceAll("[^a-zA-Z0-9]", "");
                                        }
                                        if (Name.length() == 13) {
                                            Name = "7" + Name;
                                        }
                                        // 调用replaceAll和isValidExpressNumber方法检查单号是否符合规则并打印结果
                                        // 检查是否与上一次扫描结果相同
                                        if (lastScanResult != null && lastScanResult.equals(Name)) {
                                            // 显示扫描结果
                                            updateUIWithScanResult(Name);
                                            if (time) {
                                                // 更新上一次扫描时间
                                                lastScanTime = currentTime;
                                                time = false;
                                            }
                                            Log.d("scanBarcode", currentTime + "_" + lastScanTime);
                                            if (currentTime - lastScanTime > 2000) {
                                                Toast.makeText(MainActivity.this, Name + "单号重复", Toast.LENGTH_SHORT).show();
                                                //播放提示音
                                                playSound(R.raw.danhaochongfu);
                                                // 更新上一次扫描时间
                                                time = true;
                                                Log.d("scanBarcode", Name + "单号重复" + currentTime + "_" + lastScanTime);
                                            }
                                        } else {
                                            boolean isValid = ExpressNumberValidator.isValidExpressNumber(Name);
                                            if (isValid) {
                                                // 显示扫描结果
                                                updateUIWithScanResult(Name);
                                                if (!photoList.contains(Name)) {
                                                    // 扫描成功后直接调用,播放提示
                                                    beepHelper.playBeep();
                                                    // 转换 InputImage 到 Bitmap
                                                    // 在后台线程执行转换和水印添加
                                                    Bitmap bitmap = imageToBitmap(this, mediaImage);
                                                    //保存图片
                                                    saveCapturedImageToPtFolder(Name, bitmap);
                                                    // 更新上一次扫描结果和将结果更新到lastScanResult
                                                    lastScanResult = Name;
                                                    photoList.add(Name);
                                                    time = true;
                                                    // 更新上一次扫描时间
                                                    lastScanTime = currentTime;

                                                } else {
                                                    if (!danhaoyicunzai.equals(Name)) {
                                                        Toast.makeText(MainActivity.this, Name + "单号已存在", Toast.LENGTH_SHORT).show();
                                                        //播放提示音
                                                        playSound(R.raw.rdanhaoyicunzai);
                                                        editText.setText(Name);
                                                        // 显示已存在图片
                                                        Intent intent = new Intent(this, ImageGalleryActivity.class);
                                                        intent.putExtra("key_string", Name);
                                                        startActivity(intent);
                                                        // 更新上一次扫描结果和将结果更新到danhaoyicunzai
                                                        danhaoyicunzai = Name;
                                                    }
                                                }
                                            } else {
                                                if (time) {
                                                    // 更新上一次扫描时间
                                                    lastScanTime = currentTime;
                                                    time = false;
                                                }
                                                if (currentTime - lastScanTime > 3000) {
                                                    time = true;
                                                    Toast.makeText(MainActivity.this, Name + "\n不符合快递单号规则要求，\n" +
                                                            "可点击✚添加自定义规则", Toast.LENGTH_SHORT).show();

                                                }
                                            }
                                        }
                                    });
                                }
                            }
                        })
                        .addOnCompleteListener(task -> // 确保资源释放
                                runOnUiThread(imageProxy::close));

            } else {
                Log.d("app3", "获取图像失败");
            }
        });
    }

    private void addRuleToFile(String Name, String List) {
        // 获取应用专属外部存储目录
        File externalFilesDir = getExternalFilesDir(null);
        // 检查外部存储目录是否存在
        if (externalFilesDir != null) {
            File rulesFile = new File(externalFilesDir, List + ".txt");
            try (BufferedWriter writer = new BufferedWriter(new FileWriter(rulesFile, true))) {
                writer.write(Name);
                writer.newLine();
                writer.flush();
                // 调用 updateRulesFile 方法来更新规则文件
            } catch (IOException e) {
                // 使用Log.e记录错误信息，确保您有一个TAG常量
                Log.e(TAG, "addRuleToFile: ", e);
            }
        } else {
            // 外部存储目录不可用，可以在这里处理错误或通知用户
            Log.e(TAG, "addRuleToFile: External storage directory is not available.");
        }
    }

    private void openFileWithApp(String fileName) {
        // 获取应用专属外部存储目录
        File externalFilesDir = getExternalFilesDir(null);
        if (externalFilesDir == null) {
            Log.e(TAG, "openFileWithApp: External storage directory is not available");
            Toast.makeText(this, "无法访问存储空间", Toast.LENGTH_SHORT).show();
            return;
        }

        // 创建文件对象
        File file = new File(externalFilesDir, fileName);

        // 检查文件是否存在
        if (!file.exists() || !file.isFile()) {
            Log.e(TAG, "openFileWithApp: File " + fileName + " does not exist");
            Toast.makeText(this, "文件不存在: " + fileName, Toast.LENGTH_SHORT).show();
            return;
        }

        try {
            // 获取文件的Uri
            Uri fileUri = FileProvider.getUriForFile(
                    this,
                    getPackageName() + ".fileprovider",
                    file
            );

            // 根据文件扩展名确定MIME类型
            String fileExtension = getFileExtension(fileName);
            String mimeType = getMimeTypeFromExtension(fileExtension);

            if (mimeType == null) {
                // 如果无法确定MIME类型，使用通用类型
                mimeType = "*/*";
            }

            // 创建打开文件的Intent
            Intent openIntent = new Intent(Intent.ACTION_VIEW);
            openIntent.setDataAndType(fileUri, mimeType);
            openIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

            // 验证是否有应用可以处理此Intent
            PackageManager packageManager = getPackageManager();
            if (openIntent.resolveActivity(packageManager) != null) {
                startActivity(openIntent);
            } else {
                // 没有应用可以处理此文件类型
                Toast.makeText(this, "没有应用可以打开此文件类型: " + fileExtension, Toast.LENGTH_LONG).show();

                // 作为后备方案，提供分享选项
                Toast.makeText(this, "尝试分享文件...", Toast.LENGTH_SHORT).show();
                shareFileCustom(fileName);
            }
        } catch (Exception e) {
            Log.e(TAG, "openFileWithApp error: ", e);
            Toast.makeText(this, "打开文件失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    // 辅助方法：获取文件扩展名
    private String getFileExtension(String fileName) {
        int lastDot = fileName.lastIndexOf('.');
        if (lastDot > 0) {
            return fileName.substring(lastDot + 1).toLowerCase();
        }
        return "";
    }

    // 辅助方法：根据文件扩展名获取MIME类型
    private String getMimeTypeFromExtension(String extension) {
        switch (extension) {
            case "txt":
                return "text/plain";
            case "pdf":
                return "application/pdf";
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            case "png":
                return "image/png";
            case "doc":
                return "application/msword";
            case "docx":
                return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
            case "xls":
                return "application/vnd.ms-excel";
            case "xlsx":
                return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
            case "ppt":
                return "application/vnd.ms-powerpoint";
            case "pptx":
                return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
            case "html":
            case "htm":
                return "text/html";
            default:
                return null; // 未知类型
        }
    }

    // 您已有的shareFile方法保持不变
    private void shareFileCustom(String fileName) {
        File externalFilesDir = getExternalFilesDir(null);
        if (externalFilesDir == null) {
            Log.e(TAG, "shareFile: External storage directory is not available");
            return;
        }

        File file = new File(externalFilesDir, fileName);
        if (!file.exists()) {
            Log.e(TAG, "shareFile: File " + fileName + " does not exist");
            return;
        }

        try {
            Uri fileUri = FileProvider.getUriForFile(
                    this,
                    getPackageName() + ".fileprovider",
                    file
            );

            // 创建分享Intent
            Intent shareIntent = new Intent(Intent.ACTION_SEND);
            shareIntent.setType("text/plain");
            shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
            shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

            // 查询所有能处理该Intent的应用
            PackageManager pm = getPackageManager();
            List<ResolveInfo> apps = pm.queryIntentActivities(shareIntent, PackageManager.MATCH_DEFAULT_ONLY);

            // 创建一个Intent列表，用于过滤后的应用
            List<Intent> targetedIntents = new ArrayList<>();
            List<String> packages = new ArrayList<>();
            // 允许的应用包名
            String[] allowedPackages = {
                    "com.tencent.mm",      // 微信
                    "com.tencent.mobileqq" // QQ
            };

            for (ResolveInfo resolveInfo : apps) {
                String packageName = resolveInfo.activityInfo.packageName;
                for (String allowed : allowedPackages) {
                    if (packageName.equals(allowed)) {
                        Intent targetedIntent = new Intent(Intent.ACTION_SEND);
                        targetedIntent.setType("text/plain");
                        targetedIntent.putExtra(Intent.EXTRA_STREAM, fileUri);
                        targetedIntent.setPackage(packageName);
                        targetedIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        targetedIntents.add(targetedIntent);
                        packages.add(packageName);
                        break;
                    }
                }
            }

            // 如果没有符合条件的应用，提示用户
            if (targetedIntents.isEmpty()) {
                Toast.makeText(this, "没有找到可用的应用", Toast.LENGTH_SHORT).show();
                return;
            }

            // 创建选择器Intent
            Intent chooser = Intent.createChooser(targetedIntents.remove(0), "选择分享方式");
            if (chooser == null) {
                return;
            }

            // 添加额外选项
            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));

            startActivity(chooser);

        } catch (Exception e) {
            Log.e(TAG, "shareFile error: ", e);
            Toast.makeText(this, "分享失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
    public void updateRulesFile(String List) {
        // 获取应用专属外部存储目录下的规则文件
        // 规则文件的File对象
        File rulesFile = new File(getExternalFilesDir(null), List);
        // 检查规则文件是否存在
        if (rulesFile.exists()) {
            try (BufferedReader reader = new BufferedReader(new FileReader(rulesFile))) {
                String line;
                if (List.equals("photoList.txt")) {
                    // 清空 photoList
                    photoList.clear();
                    // 逐行读取规则文件
                    while ((line = reader.readLine()) != null) {
                        photoList.add(line);

                    }
                    // 删除多余元素
                    while (photoList.size() > 2000) {
                        photoList.removeFirst(); // 移除最旧的数据
                    }
                    // 计算列表中的元素数量
                    photoList_count = photoList.size();
                    runOnUiThread(() -> {
                        textView2.setText("当前单号数量: " + photoList_count);
                    }); // 显示扫描结果视图

                }
                if (List.equals("danhaoList.txt")) {
                    // 清空 photoList
                    danhaoList.clear();
                    // 逐行读取规则文件
                    while ((line = reader.readLine()) != null) {
                        danhaoList.add(0, line);
                    }
                    // 计算列表中的元素数量
                    danhaoList_count = danhaoList.size();
                    runOnUiThread(() -> {
                        textView.setText("当前单号数量: " + danhaoList_count);
                    }); // 显示扫描结果视图


                }
            } catch (IOException e) {
                // 日志记录错误，实际应用中需要记录日志
                Log.e(TAG, "updateRulesFile: ", e);
            }
        }
    }

    public synchronized void addPhoto(String photo) {
        // 如果单号图片已存在repeat = true;
        repeat = true;
        photoList.addLast(photo); // 添加新的数据
        danhaoList.add(0, photo);
        viewModel.addItem(0, photo);

        // 计算列表中的元素数量
        photoList_count = photoList.size();
        danhaoList_count = danhaoList.size();
        runOnUiThread(() -> {
            textView2.setText(String.valueOf(photoList_count));
            textView.setText(String.valueOf(danhaoList_count));
        }); // 显示扫描结果视图
        //保存已拍照单号到文件
        addRuleToFile(photo, "photoList");
        addRuleToFile(photo, "danhaoList");
    }

    @NonNull
    private Bitmap getMutableBitmap(String fileNameBase, Bitmap rotatedBitmap) {
        // 创建Canvas和Paint对象
        Bitmap mutableBitmap = rotateBitmapIfNeeded(rotatedBitmap.copy(Bitmap.Config.ARGB_8888, true)); // 创建一个可变的副本
        Canvas canvas = new Canvas(mutableBitmap); // 现在可以在这个 Canvas 上进行绘制
        Paint paint = new Paint();
        paint.setColor(Color.RED); // 设置水印颜色
        paint.setTextSize(42); // 设置水印字体大小
        // 指定第一行水印的位置（x, y）
        int firstLineX = 40; // 第一行水印的x坐标（左上角）
        int secondLineY = mutableBitmap.getHeight() - 60;// 第一行水印的y坐标（从底部开始）
        int firstLineY = (int) (secondLineY - paint.getFontMetrics().descent - paint.getFontMetrics().leading - 36); // 稍微向上移动以放置第二行
        // 绘制第一行水印文本
        String timeStamp2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss", Locale.getDefault()).format(new Date());
        canvas.drawText(timeStamp2, firstLineX, secondLineY, paint);
        //指定第二行水印的位置（考虑到第一行文本的高度）
        canvas.drawText(fileNameBase, firstLineX, firstLineY, paint);
        return mutableBitmap;
    }

    //检查Bitmap图片方向并自动旋转
    public Bitmap rotateBitmapIfNeeded(Bitmap bitmap) {
        // 获取Bitmap的宽度和高度
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        // 创建一个Matrix对象用于旋转Bitmap
        Matrix matrix = new Matrix();

        // 根据宽度和高度判断是否需要旋转
        if (width > height) {
            // 如果宽度大于高度，则将Bitmap旋转90度
            matrix.postRotate(90);
        } else {
            // 如果宽度没有大于高度，则不需要旋转
            return bitmap;
        }

        // 创建一个新的Bitmap，应用旋转
        Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);

        // 回收原始Bitmap，避免内存泄漏
        bitmap.recycle();

        // 返回旋转后的Bitmap
        return rotatedBitmap;
    }

    //检查Bitmap图片方向并自动旋转
    public Bitmap rotateBitmapAccordingToExif(File filePath, Bitmap bitmap) {
        try {
            ExifInterface exif = new ExifInterface(filePath);
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);

            Matrix matrix = new Matrix();

            switch (orientation) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    matrix.postRotate(90);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    matrix.postRotate(180);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    matrix.postRotate(270);
                    break;
                case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
                    matrix.setScale(-1, 1); // 水平翻转
                    break;
                case ExifInterface.ORIENTATION_FLIP_VERTICAL:
                    matrix.setScale(1, -1); // 垂直翻转
                    break;
                case ExifInterface.ORIENTATION_TRANSPOSE:
                    matrix.setRotate(90); // 旋转90度，然后水平翻转
                    matrix.postScale(-1, 1);
                    break;
                case ExifInterface.ORIENTATION_TRANSVERSE:
                    matrix.setRotate(270); // 旋转270度，然后水平翻转
                    matrix.postScale(-1, 1);
                    break;
                default:
                    // 如果没有旋转信息，或者方向是默认的（即不旋转），则不做处理
                    break;
            }

            // 使用Matrix旋转Bitmap

            return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
        } catch (Exception e) {
            Log.e(TAG, "处理过程中发生错误，返回原Bitmap", e);
            return bitmap; // 如果处理过程中发生错误，返回原Bitmap
        }
    }

    private void deleteRuleFromFile(Context context, String nameToDelete) {
        // 获取应用专属外部存储目录
        File externalFilesDir = context.getExternalFilesDir(null);
        if (externalFilesDir != null) {
            File rulesFile = new File(externalFilesDir, "photoList.txt");
            try (BufferedReader reader = new BufferedReader(new FileReader(rulesFile))) {
                List<String> lines = new ArrayList<>();
                String line;
                // 逐行读取规则文件
                while ((line = reader.readLine()) != null) {
                    if (!line.equals(nameToDelete)) {
                        lines.add(line); // 只添加不等于要删除的数据的行
                    }
                }
                // 将更新后的内容写回文件
                try (BufferedWriter writer = new BufferedWriter(new FileWriter(rulesFile))) {
                    for (String remainingLine : lines) {
                        writer.write(remainingLine);
                        writer.newLine();
                    }
                    writer.flush();

                } catch (IOException e) {
                    Log.e(TAG, "deleteRuleFromFile: Error writing to file", e);
                }
            } catch (IOException e) {
                Log.e(TAG, "deleteRuleFromFile: Error reading from file", e);
            }
        } else {
            Log.e(TAG, "deleteRuleFromFile: External storage directory is not available.");
        }
    }

    @SuppressLint({"SetTextI18n", "NotifyDataSetChanged"})
    void updateUiAfterSave(Uri imageUri, String fileNameBase) {
        // 在这里更新UI，比如设置ImageView的Bitmap
        // 确保在主线程中执行
        runOnUiThread(() -> {
            // 更新UI
            // 创建ImageItem对象，这里直接使用Uri而不是字符串
            item = new ImageItem(this, imageUri, fileNameBase);
            // 添加到适配器
            mAdapter.addItem(item);
            // 刷新适配器
            mAdapter.notifyDataSetChanged();
            // 滚动到顶部以显示新图片
            mRecyclerView.setVisibility(View.VISIBLE);
            mRecyclerView.scrollToPosition(0);
            //保存已拍照单号到列表
            addPhoto(fileNameBase);
        });

    }

    @Override
    public void onItemRemoved(String fileName) {
        // 如果需要，可以在这里调用notifyDataSetChanged()来更新RecyclerView
        runOnUiThread(() -> {
            if (fileName.equals(Name)) {
                imageView1.setVisibility(View.INVISIBLE);

            }
            lastScanResult = "null";
            Toast.makeText(this, fileName + "删除图片成功", Toast.LENGTH_SHORT).show();
        });
        executor.submit(() -> {
            photoList.remove(fileName);
            danhaoList.remove(fileName);
            // 计算列表中的元素数量
            photoList_count = photoList.size();
            danhaoList_count = danhaoList.size();
            runOnUiThread(() -> {
                textView2.setText(String.valueOf(photoList_count));
                textView.setText(String.valueOf(danhaoList_count));
            }); // 显示扫描结果视图
            deleteRuleFromFile(this, fileName);
        });
    }

    //指定图片保存目录为Pictures/pt
    //保存图片都指定目录
    private void saveCapturedImageToPtFolder(String fileNameBase, Bitmap rotatedBitmap) {
        editText.setText("");
        executor.submit(() -> {
            //图片添加水印
            Bitmap mutableBitmap = getMutableBitmap(fileNameBase, rotatedBitmap);
            // 显示ImageView
            runOnUiThread(() -> {
                imageView1.setImageBitmap(mutableBitmap);
                imageView1.setVisibility(View.VISIBLE);

            });
            String timeStamp = new SimpleDateFormat("MMdd_HHmmss", Locale.getDefault()).format(new Date());
            String timeStamp1 = new SimpleDateFormat("yyyyMM", Locale.getDefault()).format(new Date());
            // 创建文件名
            String fileName = fileNameBase + "_" + timeStamp + ".jpg";
            ContentValues contentValues = new ContentValues();
            contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
            contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
//        contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, DIRECTORY_PICTURES + File.separator + "LGSAppImages" + File.separator + timeStamp1);
            // 设置图片的相对路径到手机相册的Pictures目录下
            contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM + "/" + "LGSAppImages" + "/" + timeStamp1);
            // 使用ContentResolver保存图片
            ContentResolver resolver = getContentResolver();

            try {
                Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
                if (imageUri != null) {
                    try (OutputStream os = resolver.openOutputStream(imageUri)) {
                        assert os != null;
                        mutableBitmap.compress(Bitmap.CompressFormat.JPEG, 90, os);
                        // 更新UI（在主线程中）
                        updateUiAfterSave(imageUri, fileNameBase);
                        // 通知系统更新媒体库
                        resolver.notifyChange(imageUri, null);
                    } catch (IOException e) {
                        Log.e(TAG, "保存图片时发生错误", e);
                        Toast.makeText(this, "保存图片时发生错误", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(this, "保存图片失败", Toast.LENGTH_SHORT).show();
                }
            } catch (Exception e) {
                Log.e(TAG, "保存图片时发生错误", e);
                Toast.makeText(this, "保存图片时发生错误", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
